package com.ee.chat.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ee.chat.admin.service.IChannelService;
import com.ee.chat.admin.service.IOperationService;
import com.ee.chat.common.bean.Result;
import com.ee.chat.common.dao.*;
import com.ee.chat.common.entity.*;
import com.ee.chat.common.serconfig.MyAliOSSConfig;
import com.ee.chat.common.serconfig.MyNeteaseApp;
import com.ee.chat.common.service.IChannelEarnService;
import com.ee.chat.common.service.IChannelShortUrlService;
import com.ee.chat.common.service.IGeneralService;
import com.ee.chat.common.vo.ChannelVO;
import com.ndhutu.ee.util.DateUtil;
import com.ndhutu.ee.util.MD5Util;
import com.ndhutu.ee.util.StringUtil;
import com.ndhutu.ee.util.netease.im.IMUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;

@Service
public class ChannelServiceImpl implements IChannelService {

    @Resource
    ChannelMapper channelMapper;
    @Resource
    IOperationService operationService;
    @Resource
    HostMapper hostMapper;
    @Resource
    UserMapper userMapper;
    @Resource
    IGeneralService generalService;
    @Resource
    BaseMapper baseMapper;
    @Resource
    MyAliOSSConfig ossConfig;
    @Resource
    MyNeteaseApp app;
    @Resource
    IChannelEarnService channelEarnService;
    @Resource
    SysConfigMapper sysConfigMapper;
    @Resource
    ChannelUserLogMapper channelUserLogMapper;
    @Resource
    UserInviteLogMapper userInviteLogMapper;
    @Resource
    IChannelShortUrlService channelShortUrlService;

    /**
     * 渠道列表
     * @Author Shane
     * @Date 2019/11/23 16:27
     * @param
     * @return
     **/
    @Override
    public Result list(HttpServletRequest request, Integer page, Integer limit, String keyword, Integer type) throws Exception {
        Map<String, Object> data = new HashMap<>();

        if(StringUtil.isEmpty(keyword) && type == null){
            HttpSession session = request.getSession(true);
            List<String> userPermissions = (List<String>)session.getAttribute("userPermissions");
            if(!userPermissions.contains("/channel/viewList")){
                data.put("datas", new ArrayList<>());
                data.put("total", 0);

                return Result.returnSuccess(data);
            }
        }

        Page<Map<String, Object>> p = new Page<>(page, limit);
        IPage<Map<String, Object>> iPage = channelMapper.list(p, null, keyword, type);
        List<Map<String, Object>> datas = iPage.getRecords();
        for(Map<String, Object> map : datas){
            Integer registerNum = Integer.parseInt(map.get("registerNum")+"");
            Integer rechagePeopleNum = Integer.parseInt(map.get("rechagePeopleNum")+"");
            double rechageRate;
            if(registerNum == 0){
                rechageRate = 0;
            }else{
                rechageRate = new BigDecimal(rechagePeopleNum+"").divide(new BigDecimal(registerNum+""), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).doubleValue();
            }
            map.put("rechageRate", rechageRate+"%");
        }

        data.put("datas", datas);
        data.put("total", iPage.getTotal());

        operationService.addOperationLog(request, "查看渠道列表数据");

        return Result.returnSuccess(data);
    }

    @Override
    public Result toEdit(HttpServletRequest request, Integer id) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Map<String, Object> channel= channelMapper.selectChannelVOById(id);
        if(channel == null){
            channel = new HashMap<>();
            channel.put("host_channel_first_invite_recharge_rate", Double.parseDouble(sysConfigMapper.getValue("host_channel_first_invite_recharge_rate")));
            channel.put("host_channel_first_invite_rate", Double.parseDouble(sysConfigMapper.getValue("host_channel_first_invite_rate")));
            channel.put("host_channel_second_invite_recharge_rate", Double.parseDouble(sysConfigMapper.getValue("host_channel_second_invite_recharge_rate")));
            channel.put("host_channel_second_invite_rate", Double.parseDouble(sysConfigMapper.getValue("host_channel_second_invite_rate")));
            channel.put("host_channel_first_invite_vip_rate", Double.parseDouble(sysConfigMapper.getValue("host_channel_first_invite_vip_rate")));
            channel.put("host_channel_first_invite_user_rate", Double.parseDouble(sysConfigMapper.getValue("host_channel_first_invite_user_rate")));

            channel.put("cps_channel_first_invite_recharge_rate", Double.parseDouble(sysConfigMapper.getValue("cps_channel_first_invite_recharge_rate")));
            channel.put("cps_channel_first_invite_rate", Double.parseDouble(sysConfigMapper.getValue("cps_channel_first_invite_rate")));
            channel.put("cps_channel_second_invite_rate", Double.parseDouble(sysConfigMapper.getValue("cps_channel_second_invite_rate")));
            channel.put("cps_channel_first_invite_vip_rate", Double.parseDouble(sysConfigMapper.getValue("cps_channel_first_invite_vip_rate")));

            channel.put("union_channel_first_invite_recharge_rate", Double.parseDouble(sysConfigMapper.getValue("union_channel_first_invite_recharge_rate")));
            channel.put("union_channel_first_invite_rate", Double.parseDouble(sysConfigMapper.getValue("union_channel_first_invite_rate")));
            channel.put("union_channel_second_invite_rate", Double.parseDouble(sysConfigMapper.getValue("union_channel_second_invite_rate")));
            channel.put("union_channel_first_invite_vip_rate", Double.parseDouble(sysConfigMapper.getValue("union_channel_first_invite_vip_rate")));
            channel.put("union_channel_first_invite_user_rate", Double.parseDouble(sysConfigMapper.getValue("union_channel_first_invite_user_rate")));
        }

        data.put("channel", channel);
        return Result.returnSuccess(data);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(HttpServletRequest request, ChannelVO channel) throws Exception {
        QueryWrapper<Channel> wrapper = new QueryWrapper<>();
        wrapper.eq("username", channel.getUsername());
        if(channelMapper.selectOne(wrapper) != null){
            return Result.returnFailure("用户名已经被注册");
        }

        if(channel.getUserId() != null){
            if(userMapper.selectById(channel.getUserId()) == null){
                return Result.returnFailure("用户不存在");
            }

            if(channelMapper.selectByUserId(channel.getUserId()) != null){
                return Result.returnFailure("用户已经是渠道商");
            }

            ChannelUserLog channelUserLog = channelUserLogMapper.selectByUserId(channel.getUserId());
            UserInviteLog userInviteLog = userInviteLogMapper.selectByUserId(channel.getUserId());
            if(channelUserLog != null){
                return Result.returnFailure("渠道直接邀请的用户不能成为一级渠道");
            }
            if(userInviteLog != null){
                Channel temp = channelMapper.selectByUserId(userInviteLog.getInviteUserId());
                if(temp == null){
                    return Result.returnFailure("邀请者不是渠道，不能升级为渠道");
                }

                if(temp != null && temp.getType() == 1){
                    return Result.returnFailure("邀请者是主播渠道，不能升级为渠道");
                }

                return Result.returnFailure("被邀请的用户不能成为主播渠道");
            }
        }

        if(channel.getType() == 1){ //主播渠道
            Host host = hostMapper.selectByUserId(channel.getUserId());
            if(host == null){
                return Result.returnFailure("该用户id不是主播，不能添加为主播渠道");
            }
        }else if(channel.getType() == 2 || channel.getType() == 3){  //cps渠道
            if(channel.getUserId() == null){
                QueryWrapper<User> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("phone", channel.getLinkPhone());
                User user = userMapper.selectOne(wrapper1);
                if(user != null){
                    return Result.returnFailure("该手机号已被注册使用，请更换手机号");
                }

                //注册app账号
                user = new User();
                user.setId(generalService.getNewUserId());
                user.setInviteCode(generalService.getNewInviteCode());
                user.setToken(StringUtil.getUUIDStr());
                user.setPhone(channel.getLinkPhone());
                user.setName(baseMapper.getRandomUserName());
                user.setIcon(baseMapper.getRandomUserIcon());

                //网易IM注册
                String imToken = "123456";
                String ossUrl = "https://"+ossConfig.getBucketName()+"."+ossConfig.getEndpoint()+"/";
                try {
                    IMUtil.create(app.getIdPrefix()+user.getId(), user.getName(), ossUrl+user.getIcon(), imToken, app);
                } catch(Exception e){
                    IMUtil.update(app.getIdPrefix()+user.getId(), imToken, app);
                    IMUtil.updateUinfo(app.getIdPrefix()+user.getId(), user.getName(), ossUrl+user.getIcon(), null, app);
                }
                user.setImToken(imToken);
                userMapper.insert(user);

                channel.setUserId(user.getId());
            }

        }else{
            return Result.returnFailure("渠道不存在");
        }

        //渠道注册
        channel.setCode(generalService.getNewChannelCode());
        channel.setPassword(MD5Util.encode32(channel.getPassword()));
        channelMapper.insert(channel);

        channelEarnService.updateChannelEarn(channel, 0);

        operationService.addOperationLog(request, "添加渠道，id："+channel.getId());

        //添加渠道对应落地页的短网址
        channelShortUrlService.addChannelShortUrlByPid(channel.getId());

        return Result.returnSuccess(null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result edit(HttpServletRequest request, ChannelVO channel) throws Exception {
        Channel c = channelMapper.selectById(channel.getId());
        if(!c.getPassword().equals(MD5Util.encode32(channel.getPassword()))){
            channel.setPassword(MD5Util.encode32(channel.getPassword()));
        }

        channelMapper.updateById(channel);

        channelEarnService.updateChannelEarn(channel, 1);

        operationService.addOperationLog(request, "编辑渠道，id："+channel.getId());

        return Result.returnSuccess(null);
    }

    @Override
    public Result updateStatus(HttpServletRequest request, Integer id) throws Exception {
        Channel channel = channelMapper.selectById(id);
        channel.setStatus(channel.getStatus() == 0 ? 1 : 0);
        channelMapper.updateById(channel);

        operationService.addOperationLog(request, "变更渠道状态，id："+channel.getId());

        if(channel.getStatus() == 0){
            //添加渠道对应落地页的短网址
            channelShortUrlService.addChannelShortUrlByPid(channel.getId());
        }

        return Result.returnSuccess(null);
    }

    @Override
    public Result statis(HttpServletRequest request, Integer page, Integer limit, Integer userId, String code, String time) throws Exception {
        Map<String, Object> data = new HashMap<>();

        if(StringUtil.isEmpty(code) && StringUtil.isEmpty(time) && userId == null){
            HttpSession session = request.getSession(true);
            List<String> userPermissions = (List<String>)session.getAttribute("userPermissions");
            if(!userPermissions.contains("/channel/statis/viewList")){
                data.put("datas", new ArrayList<>());
                data.put("total", 0);

                return Result.returnSuccess(data);
            }
        }

        Date beginTime = null, endTime = null;
        if(!StringUtil.isEmpty(time)){
            String[] arr = time.split(" - ");
            beginTime = DateUtil.parse(arr[0]);
            endTime = DateUtil.parse(arr[1]);
        }

        Page<Map<String, Object>> p = new Page<>(page, limit);
        IPage<Map<String, Object>> iPage = channelMapper.statis(p, userId, code, beginTime, endTime);

        data.put("datas", iPage.getRecords());
        data.put("total", iPage.getTotal());

        operationService.addOperationLog(request, "获取渠道统计列表数据");

        return Result.returnSuccess(data);
    }

    @Override
    public Result restPwd(HttpServletRequest request, Integer id) throws Exception {
        Channel channel = channelMapper.selectById(id);

        channel.setPassword(MD5Util.encode32("123456"));
        channelMapper.updateById(channel);

        operationService.addOperationLog(request, "重置渠道用户密码，id：" + id);

        return Result.returnSuccess(null);
    }
}
